package com.ybkj.daijia.config;

import com.alibaba.fastjson.JSON;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import com.ybkj.daijia.Setting;
import com.ybkj.daijia.serverUtils.SettingUtils;
import com.ybkj.daijia.common.Result;
import com.ybkj.daijia.server.zhuanxian.Car;
import com.ybkj.daijia.server.zhuanxian.Order;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.apache.commons.lang3.StringUtils;
import org.json.JSONArray;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.HttpServerErrorException;
import org.springframework.web.client.RestTemplate;

@Component
public class ZhuanxianApi {

    /**
     * 创建车辆
     */
    public static final String CREATE_CAR = "api/car/createCar";
    /**
     * 修改车辆
     */
    public static final String UPDATE_CAR = "api/car/update";
    /**
     * 修改专线车辆
     */
    public static final String UPDATE_ZHUANXIAN_CAR = "api/car/updatezhuanxiancar";
    /**
     * 根据ID删除单个车辆
     */
    public static final String DELETE_CAR = "api/car/delete";
    /**
     * 根据ID查询单个车辆
     */
    public static final String QUERY_CAR = "api/car/findOne";
    /**
     * 根据车牌号查询车辆
     */
    public static final String QUERY_CAR_CARNUMBER = "api/car/findBycarNumber";
    /**
     * 根据线路查询车辆
     */
    public static final String QUERY_CAR_LINE = "api/line/findCarByLine";
    /**
     * 多条件查询车辆
     */
    public static final String QUERY_CAR_PARAM = "api/car/findByParam";
    /**
     * 创建线路
     */
    public static final String CREATE_LINE = "api/line/createline";
    /**
     * 删除线路
     */
    public static final String DELETE_LINE = "api/line/deleteline";
    /**
     * 根据ID查询单个线路
     */
    public static final String QUERY_LINE = "api/line/findOne";
    /**
     * 修改线路
     */
    public static final String UPDATE_LINE = "api/line/updateline";
    /**
     * 多条件查询线路
     */
    public static final String QUERY_LINE_PARAM = "api/line/findByParam";
    /**
     * 多条件查询订单
     */
    public static final String QUERY_ORDER = "api/order/findByParam";
    /**
     * 查询单个订单
     */
    public static final String QUERY_ONE_ORDER = "api/order/findOne";
    /**
     * 根据客户id查询最近完成订单
     */
    public static final String COUNT_FINISHED_BY_PASSENGER_DATE = "api/order/countFinishByPassenger";
    /**
     * 创建订单
     */
    public static final String CREATE_ORDER = "api/order/create";
    public static final String CALLBACK = "api/order/callback";
    /**
     * 根据车辆id查询路线
     */
    public static final String FIND_LINES_BY_CAR = "api/line/findByCar";
    /**
     * 根据公司查询新单
     */
    public static final String FIND_NEW_ORDER = "api/order/findNewOrder";
    /**
     * 根据服务人员查询忙碌订单
     */
    public static final String FIND_ACTIVED_ORDER = "api/order/findActivedOrder";
    /**
     * 城际专线订单汇总
     */
    public static final String COMPOSITIVE = "api/order/chart";
    /**
     * 城际专线订单统计(年)
     */
    public static final String ORDERSTATISTICS = "api/order/zhuanxianDataForYear";
    /**
     * 城际专线订单统计(月)
     */
    public static final String ORDERSTATISTICSMONTH = "api/order/zhuanxianDataForMonth";
    /**
     * 城际专线订单统计(日)
     */
    public static final String ORDERSTATISTICSDAY = "api/order/zhuanxianDataForDay";
    public static final String ZHUANXIANEMPLOYORDER = "api/order/zhuanxianEmployOrder";
    public static final String ZHUANXIANHEATMAP = "api/order/zhuanxianHeatMap";
    public static final String ZHUANXIANMEMBERORDER = "api/order/zhuanxianMemberOrder";
    /**
     * 根据司机id查询明细
     */
    public static final String DRIVERORDERDETAILVO = "api/order/driverOrderDetailVo";
    public static final String DRIVERORDERDETAILCOUNT = "api/order/driverOrderDetailCount";
    /**
     * 城际专线订单类型统计
     */
    public static final String ORDERTYPESTATISTICS = "api/order/orderFromSource";
    public static final String DRIVERACHIEVEMENT = "api/order/driverAchievement";
    /**
     * 按时间查询全部公司的订单统计
     */
    public static final String COMPANYORDERSTATISTICS = "api/order/companyOrder";
    /**
     * 添加订单备注
     */
    public static final String CREATE_ORDERMEMO = "api/orderMemo/remark";
    /**
     * 销单
     */
    public static final String CANCEL_ORDER = "api/order/cancel";
    /**
     * 根据服务人员查询正在执行的订单
     */
    public static final String QUERY_EMPLOY_RUNORDER = "api/order/findRunOrderByEmployId";
    /**
     * 查询服务人员已用座位
     */
    public static final String QUERY_EMPLOY_USEDSEATING = "api/order/countSeats";
    /***
     * 派单
     */
    public static final String ORDER_PAIDAN = "api/order/paidan";
    /***
     * 派单
     */
    public static final String ORDER_AUTO_PAIDAN = "api/order/autoPaidan";
    /**
     * 推荐司机的时候判断可以派单的司机
     */
    public static final String ISRECEIVEANORDER = "api/order/isReceiveAnOrder";
    /**
     * 查询催单
     */
    public static final String QUERY_CUIDAN = "api/order/getHastenOrder";
    /**
     * 关闭催单
     */
    public static final String CLOSE_CUIDAN = "api/order/closeHasten";
    /**
     * 确认费用
     */
    public static final String CONFIRM_TASK = "api/order/confirmTask";
    /**
     * 完成订单
     */
    public static final String FINISH_TASK = "api/order/finishTask";
    public static final String CREATE_PAYRECORDORDER = "api/payRecordOrder/create";
    public static final String QUERY_PAYRECORDORDER_ONE = "api/payRecordOrder/findOne";
    public static final String TREATMENT_PAYRECORDORDER = "api/payRecordOrder/update";
    public static final String UPDATE_REALMONEY = "api/order/updateRealMoney";
    /**
     * 查询服务人员的货运订单
     */
    public static final String FIND_MYWORK = "api/order/findMyWork";
    /**
     *
     */
    public static final String COUNT_NOTPAY_BY_PASSENGER = "api/order/countByPassengerId";
    public static final String QUERY_ORDERORBIT = "api/order/findOrderOrbit";
    public static final String QUERY_RUN_ORDER_LINE = "api/order/findRunOrderByLineId";
    public static final String QUERY_RUN_ORDER_CAR = "api/order/findRunOrderByCarId";
    /**
     * 根据服务人员id分页查询完成订单
     */
    public static final String QUERY_FINISHED_BY_EMPLOY = "api/order/queryFinishOrderByEmployId";
    /**
     * 报销
     */
    public static final String BAOXIAO = "api/order/baoxiao";
    /**
     * 根据服务人员查询执行中的订单
     */
    public static final String QUERY_BY_EMPLOY = "api/order/findRunOrderByEmployId";
    /**
     * 查询服务人员评价
     */
    public static final String QUERY_ORDEREVIEW_ONE = "api/orderReview/findOne";
    /**
     * 删除评价
     */
    public static final String DELETE_ORDEREVIEW = "api/orderReview/deleteById";
    /**
     * 结算前修改结算时间为当前时间
     */
    public static final String ADD_FINISHTIME = "api/order/prepare";
    /**
     * 查询某条线路的反向线路
     */
    public static final String FIND_ReturnLine = "api/line/findReturnLine.json?lineId={lineId}&appKey={appKey}";
    public static final String COUNT_RUN_ORDER_BY_PASSENGER = "api/order/queryRunOrder?passengerId={passengerId}&appKey={appKey}";
    public static final String FINDORDER_BY_PASSENGE = "api/order/findOrderByPassenger";
    private static final Logger logger = LoggerFactory.getLogger(ZhuanxianApi.class);
    @Value("${module.zhuanxian.url}")
    private String zhuanxianBaseURL;
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private SettingUtils settingUtils;

    public String getZhuanxianBaseURL() {

        return zhuanxianBaseURL.endsWith("/") ? zhuanxianBaseURL : zhuanxianBaseURL + "/";
    }

    public void setZhuanxianBaseURL(String zhuanxianBaseURL) {
        this.zhuanxianBaseURL = zhuanxianBaseURL;
    }

    public RestTemplate getRestTemplate() {
        return restTemplate;
    }

    public void setRestTemplate(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }

    /**
     * 获取该线路的反向线路
     *
     * @param lineId
     * @return
     */
    public com.alibaba.fastjson.JSONObject findReturnLine(Long lineId, String appKey) {
        StringBuilder url = new StringBuilder();
        url.append(getZhuanxianBaseURL() + FIND_ReturnLine);
        String response = restTemplate.getForObject(url.toString(), String.class, lineId, appKey);
        com.alibaba.fastjson.JSONObject jsonObject = JSON.parseObject(response);
        return jsonObject;
    }

    public String get(String apiurl, Map<String, String> kv, Setting setting) {
        kv.put("appKey", setting.getSecKey());

        String result = null;
        try {
            result = restTemplate.getForObject(apiurl, String.class, kv);
        } catch (HttpClientErrorException e) {
            e.printStackTrace();
            logger.info("HttpClientErrorException:code:{},status:{},body:{}", e.getStatusCode(),
                e.getStatusText(), e.getResponseBodyAsString());
            result = e.getResponseBodyAsString();
        } catch (HttpServerErrorException e) {
            e.printStackTrace();
            logger.error("HttpServerErrorException:{}", e.getResponseBodyAsString());
            result = e.getResponseBodyAsString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;

    }

    public String post(String apiurl, Map<String, String> kv, Setting setting) {

        kv.put("appKey", setting.getSecKey());

        String result = null;
        try {
            result = restTemplate.postForObject(apiurl, null, String.class, kv);
        } catch (HttpClientErrorException e) {
            logger.error("HttpClientErrorException:code:{},status:{},body:{}", e.getStatusCode(),
                e.getStatusText(), e.getResponseBodyAsString());
            result = e.getResponseBodyAsString();
        } catch (HttpServerErrorException e) {
            logger.error("HttpServerErrorException:{}", e.getResponseBodyAsString());
            result = e.getResponseBodyAsString();
        }

        return result;
    }

    public String postMultiValueMap(String apiurl, MultiValueMap<String, String> kv,
        Setting setting) {

        kv.add("appKey", setting.getSecKey());

        String result = null;
        try {
            result = restTemplate.postForObject(apiurl, kv, String.class);
        } catch (HttpClientErrorException e) {
            e.printStackTrace();
            logger.error("HttpClientErrorException:code:{},status:{},body:{}", e.getStatusCode(),
                e.getStatusText(), e.getResponseBodyAsString());
            result = e.getResponseBodyAsString();
        } catch (HttpServerErrorException e) {
            logger.error("HttpServerErrorException:{}", e.getResponseBodyAsString());
            result = e.getResponseBodyAsString();
        }

        return result;
    }
/*
    public String updateCarStatus(Long truckId, Integer status, Setting setting) {
        StringBuilder builder = new StringBuilder();
        builder.append(this.getzhuanxianBaseURL() + ZhuanxianApi.UPDATE_TRUCK + "?truckId={truckId}&appKey={appKey}");
        Map<String, String> kv = new HashMap<String, String>();
        kv.put("truckId", String.valueOf(truckId));

        if (status != null) {
            builder.append("&status={status}");
            kv.put("status", String.valueOf(status));
        }

        String result = null;
        try {
            result = this.put(builder.toString(), kv, setting);

        } catch (HttpClientErrorException e) {
            result = e.getResponseBodyAsString();
        } catch (HttpServerErrorException e) {
            result = e.getResponseBodyAsString();
        }
        return result;
    }*/

    public String put(String apiurl, Map<String, String> kv, Setting setting) {
        kv.put("appKey", setting.getSecKey());

        String result = null;
        try {
            restTemplate.put(apiurl, null, kv);
        } catch (HttpClientErrorException e) {
            e.printStackTrace();
            result = e.getResponseBodyAsString();
        } catch (HttpServerErrorException e) {
            e.printStackTrace();
            logger.error("HttpServerErrorException:{}", e.getResponseBodyAsString());
            result = e.getResponseBodyAsString();
        }
        return result;

    }

    public String delete(String apiurl, Map<String, String> kv, Setting setting) {
        kv.put("appKey", setting.getSecKey());

        String result = null;

        try {
            restTemplate.delete(apiurl, kv);
        } catch (HttpClientErrorException e) {
            result = e.getResponseBodyAsString();
        } catch (HttpServerErrorException e) {
            logger.error("HttpServerErrorException:{}", e.getResponseBodyAsString());
            result = e.getResponseBodyAsString();
        }
        return result;
    }

    public Long countFinishedByPassengerAndFinishTime(Long passengerId, String orderFromSources,
        Date startDate, Date endDate, Setting setting) {
        long finishedTimes = 0;

        StringBuilder builder = new StringBuilder();
        builder.append(getZhuanxianBaseURL() + ZhuanxianApi.COUNT_FINISHED_BY_PASSENGER_DATE
            + "?appKey={appKey}");
        Map<String, String> kv = new HashMap<String, String>();

        kv.put("passengerId", String.valueOf(passengerId));
        builder.append("&passengerId={passengerId}");

        if (StringUtils.isNotBlank(orderFromSources)) {
            kv.put("orderFromSources", String.valueOf(orderFromSources));
            builder.append("&orderFromSources={orderFromSources}");
        }

        kv.put("startTime", String.valueOf(startDate.getTime()));
        builder.append("&startTime={startTime}");

        if (null != endDate) {
            kv.put("endTime", String.valueOf(endDate.getTime()));
            builder.append("&endTime={endTime}");
        }

        String result = get(builder.toString(), kv, setting);
        if (StringUtils.isNotBlank(result)) {
            JSONObject jo = new JSONObject(result);
            Integer code = jo.getInt("code");
            if (code == 0) {
                finishedTimes = jo.getLong("data");
            }
        }
        return finishedTimes;
    }

    public String post(String apiurl, MultiValueMap<String, String> kv, Setting setting) {

        kv.add("appKey", setting.getSecKey());

        Set<Entry<String, List<String>>> entries = kv.entrySet();

        Map<String, String> params = new HashMap<String, String>();
        for (Entry<String, List<String>> entry : entries) {
            List<String> values = entry.getValue();
            params.put(entry.getKey(), CollectionUtils.isEmpty(values) ? null : values.get(0));
        }

        RestTemplate rest = new RestTemplate();

        String result = null;
        try {
            result = rest.postForObject(apiurl, kv, String.class);
        } catch (HttpClientErrorException e) {
            e.printStackTrace();
            logger.error("HttpClientErrorException:code:{},status:{},body:{}", e.getStatusCode(),
                e.getStatusText(), e.getResponseBodyAsString());
            result = e.getResponseBodyAsString();
        } catch (HttpServerErrorException e) {
            e.printStackTrace();
            logger.error("HttpServerErrorException:{}", e.getResponseBodyAsString());
            result = e.getResponseBodyAsString();
        }

        return result;
    }

    public Result<Order> findOne(Long orderId, Setting setting) {

        Result<Order> result = new Result<Order>();
        result.setSuccess(false);

        Order order = null;

        StringBuilder sb = new StringBuilder();
        sb.append(getZhuanxianBaseURL() + ZhuanxianApi.QUERY_ONE_ORDER
            + "?appKey={appKey}&orderId={orderId}");

        Map<String, String> kv = new HashMap<String, String>();
        kv.put("orderId", String.valueOf(orderId));

        String resultStr = get(sb.toString(), kv, setting);

        if (null != resultStr) {
            JSONObject jo = new JSONObject(resultStr);
            Integer code = jo.getInt("code");
            if (code == 0) {
                JSONObject data = jo.getJSONObject("data");
                Gson gson = new GsonBuilder().setDateFormat(com.ybkj.daijia.constant.DateConstant.DATE_TIME_FORMATE).create();
                order = gson.fromJson(data.toString(), Order.class);
                result.setSuccess(true);
                result.setResult(order);
            } else {
                result.setSuccess(false);
                result.setMessage(jo.getString("message"));
            }
        }

        return result;

    }

    public Result<Car> findOneCar(Long carId, Setting setting) {

        Result<Car> result = new Result<Car>();
        result.setSuccess(false);

        Car car = null;

        StringBuilder sb = new StringBuilder();
        sb.append(
            getZhuanxianBaseURL() + ZhuanxianApi.QUERY_CAR + "?appKey={appKey}&carId={carId}");

        Map<String, String> kv = new HashMap<String, String>();
        kv.put("carId", String.valueOf(carId));

        String resultStr = get(sb.toString(), kv, setting);
        if (null != resultStr) {
            JSONObject jo = new JSONObject(resultStr);
            Integer code = jo.getInt("code");
            if (code == 0) {
                JSONObject data = jo.getJSONObject("data");
                Gson gson = new GsonBuilder().setDateFormat(com.ybkj.daijia.constant.DateConstant.DATE_TIME_FORMATE).create();
                car = gson.fromJson(data.toString(), Car.class);
                result.setSuccess(true);
                result.setResult(car);
            } else {
                result.setSuccess(false);
                result.setMessage(jo.getString("message"));
            }
        }

        return result;

    }

    public Result<Order> baoxiao(Long orderId, BigDecimal money, Setting setting) {

        Result<Order> vo = new Result<Order>();

        MultiValueMap<String, String> kv = new LinkedMultiValueMap<String, String>();

        kv.add("orderId", String.valueOf(orderId));
        kv.add("baoxiaoMoney", String.valueOf(money));

        String result = postMultiValueMap(getZhuanxianBaseURL() + ZhuanxianApi.BAOXIAO, kv,
            setting);

        if (StringUtils.isNotBlank(result)) {
            JSONObject jo = new JSONObject(result);
            Integer code = jo.getInt("code");
            if (code == 0) {
                vo.setSuccess(true);
            } else {
                String message = jo.getString("message");
                vo.setMessage(message);
            }
        } else {
            vo.setMessage("内部服务器错误");
        }

        return vo;

    }

    public List<Order> findActivedOrdersByDriver(Long employId, Setting setting) {
        StringBuilder builder = new StringBuilder();
        builder.append(getZhuanxianBaseURL()).append(ZhuanxianApi.FIND_ACTIVED_ORDER)
            .append("?appKey={appKey}");
        Map<String, String> kv = new HashMap<String, String>();

        kv.put("employId", String.valueOf(employId));
        builder.append("&employId={employId}");

        List<Order> list = new ArrayList<Order>();
        String result = get(builder.toString(), kv, setting);
        if (null != result) {
            JSONObject jo = new JSONObject(result);
            Integer code = jo.getInt("code");
            if (code == 0) {
                JSONArray data = jo.getJSONArray("data");
                Gson gson = new GsonBuilder().setDateFormat(com.ybkj.daijia.constant.DateConstant.DATE_TIME_FORMATE).create();
                list = gson.fromJson(data.toString(), new TypeToken<List<Order>>() {
                }.getType());
            }
        }
        return list;
    }

    public Result<Order> addFinishTime(Long orderId, Setting setting) {

        Result<Order> vo = new Result<Order>();

        MultiValueMap<String, String> kv = new LinkedMultiValueMap<String, String>();

        kv.add("orderId", String.valueOf(orderId));

        String result = post(getZhuanxianBaseURL() + ZhuanxianApi.ADD_FINISHTIME, kv, setting);

        if (StringUtils.isNotBlank(result)) {
            JSONObject jo = new JSONObject(result);
            Integer code = jo.getInt("code");
            if (code == 0) {
                Boolean data = jo.getBoolean("data");
                vo.setSuccess(data);
                return vo;
            } else {
                String message = jo.getString("message");
                vo.setMessage(message);
            }
        } else {
            vo.setMessage("内部服务器错误");
        }

        return vo;

    }

    public List<Map<String, Object>> findOrderByPassenge(Long passengerId, Integer page,
        Integer rows, Setting setting) {
        List<Map<String, Object>> list = new ArrayList<>();
        StringBuilder builder = new StringBuilder();
        builder.append(getZhuanxianBaseURL()).append(ZhuanxianApi.FINDORDER_BY_PASSENGE)
            .append("?appKey={appKey}");
        Map<String, String> kv = new HashMap<String, String>();
        kv.put("passengerId", String.valueOf(passengerId));
        builder.append("&passengerId={passengerId}");
        kv.put("page", String.valueOf(page));
        builder.append("&page={page}");
        kv.put("rows", String.valueOf(rows));
        builder.append("&rows={rows}");
        String result = get(builder.toString(), kv, setting);
        if (null != result) {
            JSONObject jo = new JSONObject(result);
            Integer code = jo.getInt("code");
            if (code == 0) {
                JSONObject data = jo.getJSONObject("data");
                JSONArray content = data.getJSONArray("rows");
                for (int i = 0; i < content.length(); i++) {
                    JSONObject jsonObject = content.getJSONObject(i);
                    Map<String, Object> map = new HashMap<>();
                    for (Object key : jsonObject.keySet()) {
                        String keyStr = String.valueOf(key);
                        Object o = jsonObject.get(keyStr);
                        if ("serverTime".equals(keyStr)) {
                            map.put(keyStr, Long.valueOf(String.valueOf(o)));
                        } else {
                            map.put(keyStr, String.valueOf(o));
                        }
                    }
                    list.add(map);
                }

            }
        }
        return list;
    }

    public String getOrderByOrderNo(String orderNo) {
        StringBuilder builder = new StringBuilder();
        builder.append(getZhuanxianBaseURL()).append(ZhuanxianApi.QUERY_ORDER)
            .append(".json?appKey={appKey}");
        builder.append("&orderNo={orderNo}");
        Map<String, String> kv = new HashMap<>();
        kv.put("appKey", settingUtils.get().getSecKey());
        kv.put("orderNo", orderNo);
        try {
            String jsonStr = restTemplate.getForObject(builder.toString(), String.class, kv);
            if (null != jsonStr) {
                com.alibaba.fastjson.JSONObject jsonObject = JSON.parseObject(jsonStr);
                if (0 == jsonObject.getInteger("code")) {
                    com.alibaba.fastjson.JSONObject data = jsonObject.getJSONObject("data");
                    if (1 == data.getInteger("total")) {
                        com.alibaba.fastjson.JSONArray rows = data.getJSONArray("rows");
                        com.alibaba.fastjson.JSONObject obj = rows.getJSONObject(0);
                        return obj.getString("employName");
                    }
                } else {

                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public long countRunOrderByPassenger(Long passengerId, Setting setting) {
        long activedTimes = 0;

        StringBuilder builder = new StringBuilder();
        builder.append(getZhuanxianBaseURL() + COUNT_RUN_ORDER_BY_PASSENGER);
        Map<String, String> kv = new HashMap<String, String>();

        kv.put("passengerId", String.valueOf(passengerId));

        String result = get(builder.toString(), kv, setting);
        if (StringUtils.isNotBlank(result)) {
            JSONObject jo = new JSONObject(result);
            Integer code = jo.getInt("code");
            if (code == 0) {
                activedTimes = jo.getLong("data");
            }
        }
        return activedTimes;
    }
}
